package cn.t.facade.order;


import cn.t.constants.CommonConstants;
import cn.t.converter.order.WorkOrderDTOConverter;
import cn.t.core.exception.BizException;
import cn.t.core.facade.FacadeImpl;
import cn.t.core.mode.PageInfoDTO;
import cn.t.core.mode.PageQueryDTO;
import cn.t.core.mode.YesNoEnum;
import cn.t.dto.api.WorkOrderCreateRequestDTO;
import cn.t.dto.device.RoleSkuReq;
import cn.t.dto.device.UserRoleSkuDTO;
import cn.t.dto.order.ExcelWorkOrderDTO;
import cn.t.dto.order.WorkOrderCreateDTO;
import cn.t.dto.order.WorkOrderDTO;
import cn.t.dto.sku.SkuDTO;
import cn.t.enums.PickStatusEnum;
import cn.t.core.enums.base.CommonError;
import cn.t.enums.order.ErrorEnum;
import cn.t.enums.order.WorkOrderTypeEnum;
import cn.t.enums.order.WorkStatusEnum;
import cn.t.facade.device.CargowayFacade;
import cn.t.facade.device.CargowaySkuFacade;
import cn.t.facade.sku.SkuFacade;
import cn.t.model.common.MqProcessLogDO;
import cn.t.model.device.CargowaySkuDO;
import cn.t.model.device.DeviceDO;
import cn.t.model.order.OrderDO;
import cn.t.model.order.OrderDetailDO;
import cn.t.model.order.WorkOrderDO;
import cn.t.model.order.WorkOrderDetailDO;
import cn.t.model.sku.SkuDO;
import cn.t.model.user.UserQueryDO;
import cn.t.request.WorkOrderReq;
import cn.t.response.Response;
import cn.t.runtime.dto.DeviceWorkOrderRequest;
import cn.t.service.common.MqProcessLogService;
import cn.t.service.device.CargowaySkuService;
import cn.t.service.device.DeviceService;
import cn.t.service.order.OrderDetailService;
import cn.t.service.order.WorkOrderDetailService;
import cn.t.service.order.WorkOrderService;
import cn.t.service.sku.SkuService;
import cn.t.service.user.CostCenterService;
import cn.t.service.user.CustomerFirmService;
import cn.t.service.user.UserPassportService;
import cn.t.service.user.UserQueryService;
import cn.t.utils.AESUtil;
import cn.t.utils.ExcelUtil;
import cn.t.utils.JsonUtil;
import cn.t.vo.andriod.AndroidDeviceVO;
import cn.t.vo.andriod.AndroidWorkOrderVO;
import cn.t.vo.ent.EntWorkOrderDetailVO;
import cn.t.vo.order.WorkOrderVO;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * 工单表(WorkOrder)服务编排
 */
@Slf4j
@Service
public class WorkOrderFacade extends FacadeImpl<WorkOrderDTO, WorkOrderDO, WorkOrderDTOConverter, WorkOrderService> {

    @Resource
    private CustomerFirmService customerFirmService;
    @Resource
    private CostCenterService costCenterService;
    @Resource
    private WorkOrderDetailService workOrderDetailService;
    @Resource
    private MqProcessLogService mqProcessLogService;

    @Resource
    private OrderDetailService orderDetailService;

    @Resource
    private DeviceService deviceService;
    @Resource
    private UserQueryService userQueryService;
    @Resource
    private SkuService skuService;

    @Resource
    private CargowaySkuService cargowaySkuService;
    @Resource
    private CargowaySkuFacade cargowaySkuFacade;

    @Resource
    private SkuFacade skuFacade;



    public PageInfoDTO<WorkOrderVO> page(PageQueryDTO<WorkOrderReq> req) {
        WorkOrderDO queryParam = this.converter.req2Do(req.getParam());

        // 根据skuCode, skuName 到工单明细里查询工单id
        if (StringUtils.hasText(req.getParam().getSkuCode()) || StringUtils.hasText(req.getParam().getSkuName())) {
            List<WorkOrderDetailDO> workOrderDetails = this.workOrderDetailService.getWorkOrderDetails(req.getParam().getSkuCode(), req.getParam().getSkuName(), null);
            List<String> workOrderSns = workOrderDetails.stream().map(WorkOrderDetailDO::getWorkOrderSn).collect(Collectors.toList());
            queryParam.setWorkOrderSns(workOrderSns);
        }

        List<WorkOrderDO> list = this.service.findByModel(queryParam, req.getStart(), req.getPageSize(), "gmt_created", " desc");
        // 所属公司
        List<Long> firmIds = list.stream().map(WorkOrderDO::getFirmId).collect(Collectors.toList());
        Map<Long, String> idNameMap = this.customerFirmService.getFirmIdNameMap(firmIds);
        // 成本中心
        List<Long> costCenterIds = list.stream().map(WorkOrderDO::getCostCenterId).collect(Collectors.toList());
        Map<Long, String> costCenterIdNameMap = this.costCenterService.getCostCenterIdNameMap(costCenterIds);
        List<WorkOrderVO> workOrders = list.stream().map(f -> this.converter.do2Vo(f, idNameMap.get(f.getFirmId()), costCenterIdNameMap.get(f.getCostCenterId()))).collect(Collectors.toList());

        long total = this.service.count(queryParam);

        return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), total, workOrders);
    }

    public void export(WorkOrderReq request, HttpServletResponse response, AbstractColumnWidthStyleStrategy customerConfig) {

        WorkOrderDO queryParam = this.converter.req2Do(request);
        List<WorkOrderDetailDO> workOrderDetails;
        List<WorkOrderDO> workOrders;

        // 根据skuCode, skuName 到工单明细里查询工单id
        if (StringUtils.hasText(request.getSkuCode()) || StringUtils.hasText(request.getSkuName())) {
            workOrderDetails = this.workOrderDetailService.getWorkOrderDetails(request.getSkuCode(), request.getSkuName(), null);
            List<String> workOrderSns = workOrderDetails.stream().map(WorkOrderDetailDO::getWorkOrderSn).collect(Collectors.toList());
            queryParam.setWorkOrderSns(workOrderSns);

            workOrders = this.service.findByModel(queryParam, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
        } else {
            workOrders = this.service.findByModel(queryParam, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
            List<String> workOrderSns = workOrders.stream().map(WorkOrderDO::getWorkOrderSn).collect(Collectors.toList());
            workOrderDetails = this.workOrderDetailService.getWorkOrderDetails(null, null, workOrderSns);
        }

        if (CollectionUtils.isEmpty(workOrders) || CollectionUtils.isEmpty(workOrderDetails)) {
            throw new BizException(ErrorEnum.NO_DATA, ErrorEnum.NO_DATA.getMessage());
        }
        List<String> workOrderSns = workOrders.stream().map(WorkOrderDO::getWorkOrderSn).collect(Collectors.toList());
        List<Long> firmIds = workOrders.stream().map(WorkOrderDO::getFirmId).collect(Collectors.toList());
        List<Long> costCenterIds = workOrders.stream().map(WorkOrderDO::getCostCenterId).collect(Collectors.toList());

        List<ExcelWorkOrderDTO> list = this.getExcelData(workOrderDetails, workOrders, workOrderSns, firmIds, costCenterIds);

        if (list.size() > 50000) {
            throw new BizException(ErrorEnum.DATA_TO_MANY, String.format(ErrorEnum.DATA_TO_MANY.getMessage(), "目前暂支持导出50000行明细, 请缩短时间范围后重试"));
        }

        list = list.stream().sorted(Comparator.comparing(ExcelWorkOrderDTO::getGmtCreated)).collect(Collectors.toList());
        try {
            ExcelUtil.setHeader(response, URLEncoder.encode("工单明细列表", "UTF-8"));

            ServletOutputStream outputStream = response.getOutputStream();
            EasyExcelFactory.write(outputStream, ExcelWorkOrderDTO.class).sheet("工单明细列表").registerWriteHandler(customerConfig).doWrite(list);
        } catch (Exception e) {
            log.error("导出工单明细列表失败", e);
        }
    }

    private List<ExcelWorkOrderDTO> getExcelData(List<WorkOrderDetailDO> workOrderDetails, List<WorkOrderDO> workOrders, List<String> workOrderSns, List<Long> firmIds, List<Long> costCenterIds) {
        List<ExcelWorkOrderDTO> excelData = new ArrayList<>();

        // 推送日志
        Map<String, MqProcessLogDO> mqLogMap = this.mqProcessLogService.getMqLogMap(workOrderSns);
        // 所属公司
        Map<Long, String> idNameMap = this.customerFirmService.getFirmIdNameMap(firmIds);
        // 成本中心
        Map<Long, String> costCenterIdNameMap = this.costCenterService.getCostCenterIdNameMap(costCenterIds);

        Map<String, List<WorkOrderDetailDO>> orderDetailMap = workOrderDetails.stream().collect(Collectors.groupingBy(WorkOrderDetailDO::getWorkOrderSn));
        workOrders.forEach(f -> {
            List<WorkOrderDetailDO> orderDetailDOS = orderDetailMap.get(f.getWorkOrderSn());
            if (CollectionUtils.isEmpty(orderDetailDOS)) {
                return;
            }

            MqProcessLogDO mqLog = mqLogMap.get(f.getWorkOrderSn());
            Date pushTime = mqLog == null ? null : mqLog.getGmtCreated();

            orderDetailDOS.forEach(d -> {
                ExcelWorkOrderDTO excelWorkOrder = this.converter.data2ExcelDto(f, d, pushTime, idNameMap.get(f.getFirmId()), costCenterIdNameMap.get(f.getCostCenterId()));
                excelData.add(excelWorkOrder);
            });
        });

        return excelData;
    }

    public PageInfoDTO<WorkOrderDetailDO> detailPage(PageQueryDTO<WorkOrderDetailDO> request) {
        List<WorkOrderDetailDO> workOrderDetailDOS = this.workOrderDetailService.findByModel(request.getParam(), request.getStart(), request.getPageSize(), " gmt_created", " desc");
        long total = this.workOrderDetailService.count(request.getParam());
        return new PageInfoDTO<>(request.getPageNo(), request.getPageSize(), total, workOrderDetailDOS);
    }

    public void removeByWorkOrderSn(String workOrderSn) {
        if (ObjectUtils.isEmpty(workOrderSn)) {
            WorkOrderDO workOrder = service.getWorkOrder(workOrderSn);
            if (workOrder != null && workOrder.getWorkOrderSource().equals(CommonConstants.TWO)) {
                List<WorkOrderDetailDO> curWorkOrderDetails = this.workOrderDetailService.getWorkOrderDetails(null, null, Collections.singletonList(workOrderSn));
                curWorkOrderDetails.forEach(workOrderDetailDO -> workOrderDetailDO.setIsDeleted(YesNoEnum.TRUE));
                workOrderDetailService.updateBatchInfo(curWorkOrderDetails);
                workOrder.setIsDeleted(YesNoEnum.TRUE);
                service.update(workOrder);
            }
        }
    }
    public WorkOrderDO getWorkOrder(String workOrderSn) {
        return service.getWorkOrder(workOrderSn);
    }
public String addWorkOrderByOrder(OrderDO orderDO) {
    UserQueryDO userQueryDO1 = new UserQueryDO();
    userQueryDO1.setId(orderDO.getUserId());
    UserQueryDO userQueryDO = userQueryService.findUserByFirmId(userQueryDO1).stream().findFirst().orElse(null);
    List<OrderDetailDO> allList = orderDetailService.queryListByOrderSn(new OrderDetailDO(orderDO.getOrderSn()));
    if (!ObjectUtils.isEmpty(allList)) {
        return this.addWorkOrder(orderDO, userQueryDO == null ? null : userQueryDO.getEmployeeCode(), allList);
    }
    return null;
}

    @Transactional(rollbackFor = Exception.class)
    public Response<Boolean> createWorkOrder(WorkOrderCreateRequestDTO request) {
        String workOrderSn;
        try {
            WorkOrderCreateDTO workOrderCreateDTO = this.converter.createReq2Model(request);
            //解密公司id firmId
            if (StringUtils.hasText(request.getCompanyId())) {
                    DeviceDO device = deviceService.findById(Long.valueOf(request.getDeviceId()));
                workOrderCreateDTO.setFirmId(device.getFirmId());
            }

            workOrderSn = this.createWorkOrder(workOrderCreateDTO);
            return StringUtils.hasText(workOrderSn) ? Response.success(Boolean.TRUE) : Response.error("400", "创建工单失败");
        } catch (Exception e) {
            log.error("nidec创建工单失败，请求参数：\n {}", JsonUtil.stringify(request), e);
            return Response.error("400", "创建工单失败: " + e.getMessage());
        }
    }


    public String addWorkOrder(OrderDO orderDO, String empNo, List<OrderDetailDO> orderDetailDOList) {
        if (orderDO.getWorkOrderSn() != null) {
            return orderDO.getWorkOrderSn();
        }
        WorkOrderDO workOrderDO = new WorkOrderDO();
        // 获取工单号
        String workOrderSn = this.service.getWorkOrderSn(CommonConstants.WORK_START_DEFAULT_SY);
        orderDO.setWorkOrderSn(workOrderSn);
        workOrderDO.setWorkOrderSn(workOrderSn);
        workOrderDO.setEmpNo(empNo);
        workOrderDO.setStatus(WorkStatusEnum.COMPLETED.getCode());
        converter.data2Do(orderDO, workOrderDO);
        service.add(workOrderDO);
        workOrderDetailService.addDetailList(orderDetailDOList, orderDO);
        return workOrderSn;
    }

    public String createWorkOrder(WorkOrderCreateDTO workOrderCreateDTO) {

        if (workOrderCreateDTO == null || CollectionUtils.isEmpty(workOrderCreateDTO.getPlanData())) {
            return CommonConstants.BLANK;
        }

        // 根据工号查用户id
        UserQueryDO queryParams = new UserQueryDO();
        queryParams.setEmployeeCode(workOrderCreateDTO.getAccount());
        UserQueryDO user = this.userQueryService.findOne(workOrderCreateDTO.getAccount(), null, workOrderCreateDTO.getFirmId());
        if (user == null) {
            log.error("工号不存在，工号：{}", workOrderCreateDTO.getAccount());
            throw new BizException(CommonError.ILLEGAL_PARAMETER, "智能柜未配置该用户！");
        }
        String userId = String.valueOf(user.getId());

        // 1.校验工单是否存在，存在的话更新创建人
        WorkOrderDO workOrderDO = this.service.getWorkOrder(workOrderCreateDTO.getWorkOrderSn());
        if (workOrderDO != null && userId != null) {
            workOrderDO.setCreator(userId);
            this.service.updateWorkOrder(workOrderDO);

            WorkOrderDetailDO workOrderDetailDO = new WorkOrderDetailDO();
            workOrderDetailDO.setWorkOrderSn(workOrderCreateDTO.getWorkOrderSn());
            workOrderDetailDO.setCreator(userId);
            this.workOrderDetailService.conditionUpdate(workOrderCreateDTO.getWorkOrderSn(), workOrderDetailDO);
            return workOrderDO.getWorkOrderSn();
        }

        // 不存在则新增工单
        //插入工单头表
        workOrderDO = this.converter.createDto2Do(workOrderCreateDTO, userId);

        // 冗余 (领料员卡号、领料员姓名、成本中心)
        workOrderDO.setNickname(ObjectUtils.isEmpty(user.getIndividualName()) ? workOrderCreateDTO.getName() : user.getIndividualName());
        workOrderDO.setCardNo(user.getCardCode());
        workOrderDO.setCostCenterId(user.getCostCenterId());
        workOrderDO.setEmpNo(user.getEmployeeCode());
        workOrderDO.setWorkOrderSource(CommonConstants.ONE);

        // 根据客户定制化设置工单数据
        this.service.customizeWorkOrder(workOrderDO, workOrderCreateDTO.getCustomerCode());

        this.service.add(workOrderDO);
        // 插入明细表
        List<WorkOrderDetailDO> workOrderDetailDOS = new ArrayList<>();

        // 获取商品map
        List<String> skuCodes = workOrderCreateDTO.getPlanData().stream().map(WorkOrderCreateDTO.WorkOrderCreateItem::getSku).collect(Collectors.toList());
        List<SkuDO> skuDOS = this.skuService.findModelList(skuCodes);

        workOrderCreateDTO.getPlanData().forEach(f -> {
            // 商品名称
            SkuDO skuDO = skuDOS.stream().filter(s -> f.getSku().equals(s.getSkuCode())).findFirst().orElse(null);
            String skuName = skuDO == null ? CommonConstants.BLANK : skuDO.getSkuName();
            String skuImg = skuDO == null ? CommonConstants.BLANK : skuDO.getSkuImg();
            WorkOrderDetailDO workOrderDetailDO = this.converter.createDto2DetailDo(f, workOrderCreateDTO, skuName, userId, skuImg);
            workOrderDetailDOS.add(workOrderDetailDO);
        });

        this.workOrderDetailService.addBatch(workOrderDetailDOS);
        workOrderCreateDTO.setWorkOrderSn(workOrderDO.getWorkOrderSn());
        return workOrderDO.getWorkOrderSn();
    }

    public List<AndroidWorkOrderVO> getWorkOrders(DeviceWorkOrderRequest request) {
        // 补货，已审批
        if (5 == request.getType()) {
            return this.getWorkOrders(request.getUserId(), null, Lists.newArrayList(WorkStatusEnum.WAIT_DO.getCode()), WorkOrderTypeEnum.REPLENISH.getCode());
        }
        //领料，已审批
        return this.getWorkOrders(request.getUserId(), request.getImei(), Lists.newArrayList(WorkStatusEnum.WAIT_DO.getCode(), WorkStatusEnum.PART_COMPLETED.getCode()), WorkOrderTypeEnum.PICK.getCode());
    }


    private List<AndroidWorkOrderVO> getWorkOrders(Long userId, String imei, List<Integer> status, int type) {

        // 获取设备sku 和 客户物料
        List<DeviceDO> devices = this.deviceService.getDevicesByImei(imei);
        if (CollectionUtils.isEmpty(devices)) {
            return Collections.emptyList();
        }
        Long firmId = devices.stream().map(DeviceDO::getFirmId).findFirst().get();
        List<Long> deviceIds = devices.stream().map(DeviceDO::getId).collect(toList());
        // 获取设备 sku
        List<CargowaySkuDO> cargowaySkuDOS = this.cargowaySkuService.getDeviceSkuList(deviceIds);
        List<String> skuCodes = cargowaySkuDOS.stream().map(CargowaySkuDO::getSkuCode).collect(toList());
        // 获取sku位置信息
        Map<String, List<String>> skuLocationMap = this.cargowaySkuService.getSkuLocation(skuCodes, deviceIds);

        // 获取客户物料
        // 用户信息
        UserQueryDO userInfo = userQueryService.findByUserId(firmId, userId);

        if (userInfo == null || userInfo.getEmployeeCode() == null) {
            log.error("工号不存在，用户：{}", userId);
            throw new BizException(CommonError.ILLEGAL_PARAMETER, "智能柜未配置该用户！");
        }
        // 查询工单
        WorkOrderDO queryParams = new WorkOrderDO();
        queryParams.setEmpNo(userInfo.getEmployeeCode());
        queryParams.setStatusList(status);
        queryParams.setDocType(type);
        queryParams.setExpired(false);
        queryParams.setWorkOrderSource(CommonConstants.ONE);
        List<WorkOrderDO> workOrders = this.service.findByModel(queryParams, CommonConstants.ZERO, Integer.MAX_VALUE, " id ", " desc ");

        if (CollectionUtils.isEmpty(workOrders)) {
            return new ArrayList<>();
        }

        List<String> workOrderSns = workOrders.stream().map(WorkOrderDO::getWorkOrderSn).collect(toList());
        // 查询工单明细
        Map<String, List<WorkOrderDetailDO>> workOrderDetailMap = getWorkOrderDetailMap(workOrderSns);
        // sku 信息
        List<SkuDO> skuDOS = this.skuService.findModelList(skuCodes);
        Map<String, SkuDO> skuMap = skuDOS.stream().collect(Collectors.toMap(SkuDO::getSkuCode, Function.identity(), (a, b) -> a));

        List<AndroidWorkOrderVO> androidWorkOrderVOS = new ArrayList<>();
        workOrders.forEach(workOrder -> {
            AndroidWorkOrderVO androidWorkOrderVO = getAndroidWorkOrderVO(workOrderDetailMap, skuMap, workOrder, skuLocationMap);

            androidWorkOrderVOS.add(androidWorkOrderVO);
        });
        return androidWorkOrderVOS;
    }

    public AndroidWorkOrderVO detail(String workOrderSn, String imei) {
        // 获取设备信息
        List<DeviceDO> devices = this.deviceService.getDevicesByImei(imei);
        List<Long> deviceIds = devices.stream().map(DeviceDO::getId).collect(toList());

        // 查询工单
        WorkOrderDO workOrder = this.service.getWorkOrder(workOrderSn);
        if (workOrder == null) {
            throw new BizException(ErrorEnum.NO_DATA, "工单不存在:" + workOrderSn);
        }

        // 查询工单明细
        WorkOrderDetailDO detailQueryParams = new WorkOrderDetailDO();
        detailQueryParams.setWorkOrderSn(workOrderSn);
        List<WorkOrderDetailDO> workOrderDetails = this.workOrderDetailService.findByModel(detailQueryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
        // 工单明细分组
        Map<String, List<WorkOrderDetailDO>> workOrderDetailMap = workOrderDetails.stream().collect(Collectors.groupingBy(WorkOrderDetailDO::getWorkOrderSn));

        List<String> skuCodes = workOrderDetails.stream().map(WorkOrderDetailDO::getSkuCode).collect(toList());

        // 获取sku位置信息
        Map<String, List<String>> skuLocationMap = this.cargowaySkuService.getSkuLocation(skuCodes, deviceIds);

        // 获取客户物料

        // sku 信息
        List<SkuDO> skuDOS = this.skuService.findModelList(skuCodes);
        Map<String, SkuDO> skuMap = skuDOS.stream().collect(Collectors.toMap(SkuDO::getSkuCode, Function.identity(), (a, b) -> a));

        return getAndroidWorkOrderVO(workOrderDetailMap, skuMap, workOrder, skuLocationMap);
    }

    private Map<String, List<WorkOrderDetailDO>> getWorkOrderDetailMap(List<String> workOrderSns) {
        WorkOrderDetailDO detailQueryParams = new WorkOrderDetailDO();
        detailQueryParams.setWorkOrderSns(workOrderSns);
        List<WorkOrderDetailDO> workOrderDetails = this.workOrderDetailService.findByModel(detailQueryParams, CommonConstants.ZERO, Integer.MAX_VALUE, null, null);
        // 工单明细分组
        return workOrderDetails.stream().collect(Collectors.groupingBy(WorkOrderDetailDO::getWorkOrderSn));
    }

    private AndroidWorkOrderVO getAndroidWorkOrderVO(Map<String, List<WorkOrderDetailDO>> workOrderDetailMap, Map<String, SkuDO> skuMap, WorkOrderDO workOrder, Map<String, List<String>> skuLocationMap) {
        AndroidWorkOrderVO androidWorkOrderVO = new AndroidWorkOrderVO();

        List<WorkOrderDetailDO> currentWorkOrderDetails = workOrderDetailMap.get(workOrder.getWorkOrderSn());

        androidWorkOrderVO.setWorkOrderSn(workOrder.getWorkOrderSn());
        androidWorkOrderVO.setUserId(workOrder.getCreator());
        androidWorkOrderVO.setUserName(workOrder.getNickname());
        androidWorkOrderVO.setExpireTime(workOrder.getGmtExpire());

        Map<String, String> skuCargowayMap = new HashMap<>();
        skuLocationMap.forEach((skuCode, val) -> {
            String cargowayNos = val.get(0).split(";")[1].split(":")[1];
            skuCargowayMap.put(skuCode, cargowayNos.trim());
        });

        if (!CollectionUtils.isEmpty(currentWorkOrderDetails)) {
            List<AndroidWorkOrderVO.WorkOrderDetail> details = currentWorkOrderDetails.stream()
                    .map(f -> converter.data2AndroidWorkOrderDetail(f, skuMap.containsKey(f.getSkuCode()),

                            skuMap.get(f.getSkuCode()) == null ? new SkuDO() : skuMap.get(f.getSkuCode()), skuCargowayMap.get(f.getSkuCode())))
                    .collect(Collectors.toList());
            androidWorkOrderVO.setDetails(details);
        }
        return androidWorkOrderVO;
    }





    public EntWorkOrderDetailVO entWorkOrderDetail(Long id) {
        // 查询工单信息
        WorkOrderDO workOrderDO = this.service.findById(id);
        if (workOrderDO == null) {
            throw new BizException(ErrorEnum.NO_DATA, id + "工单不存在");
        }

        // 查询工单明细信息
        List<WorkOrderDetailDO> workOrderDetailDOS = this.workOrderDetailService.getWorkOrderDetails(null, null, Lists.newArrayList(workOrderDO.getWorkOrderSn()));
        List<String> skuCodes = workOrderDetailDOS.stream().map(WorkOrderDetailDO::getSkuCode).collect(toList());

        List<EntWorkOrderDetailVO.SkuInfo> items = new ArrayList<>();

        if (!CollectionUtils.isEmpty(skuCodes)) {

            // 查询公司设备
            List<DeviceDO> devices = this.deviceService.getDeviceList(null, workOrderDO.getFirmId(), null);
            if (CollectionUtils.isEmpty(devices)) {
                throw new BizException(ErrorEnum.NO_DATA, id + "工单关联设备不存在");
            }
            List<Long> deviceIds = devices.stream().map(DeviceDO::getId).collect(toList());

            // 查询货道商品
            Map<String, List<String>> skuLocationMap = this.cargowaySkuService.getSkuLocation(skuCodes, deviceIds);

            items = workOrderDetailDOS.stream()
                    .map(f -> converter.do2EntDetailSku(f, skuLocationMap.get(f.getSkuCode()))).collect(toList());
        }
        return this.converter.do2EntDetail(workOrderDO, items);
    }


    public  PageInfoDTO<UserRoleSkuDTO>  querySkuRoleByUser(PageQueryDTO<RoleSkuReq> req, AndroidDeviceVO device ) {
        RoleSkuReq param = req.getParam();

        // 查询工单明细
        Map<String, List<WorkOrderDetailDO>> workOrderDetailMap = getWorkOrderDetailMap(Collections.singletonList(param.getWorkOrderSn()));
        if (CollectionUtils.isEmpty(workOrderDetailMap)){
            return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), 0, null);
        }
        List<WorkOrderDetailDO> workOrderDetails = workOrderDetailMap.get(param.getWorkOrderSn());
        if (ObjectUtils.isEmpty(param.getSkuCodeOrName())){
            //根据sku 和名字 模糊查询
            workOrderDetails=  workOrderDetails.stream() .filter(workOrderDetailDO -> org.apache.commons.lang3.StringUtils.isNotBlank(workOrderDetailDO.getSkuName()) && (workOrderDetailDO.getSkuName().contains(param.getSkuCodeOrName()) || workOrderDetailDO.getSkuCode().contains(param.getSkuCodeOrName())))
                    .collect(Collectors.toList());
        }

        List<WorkOrderDetailDO> listDetail = workOrderDetails.stream().distinct()
                .skip((long) req.getStart() * req.getPageSize())
                .limit(req.getPageSize())
                .collect(toList());
        List<String> skuCodes = listDetail.stream().map(WorkOrderDetailDO::getSkuCode).distinct().collect(toList());

        if (CollectionUtils.isEmpty(skuCodes)) {
            return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), 0, null);

        }

        //过滤掉没有库存的sku
        Long deviceId = device.getDeviceId();
        List<CargowaySkuDO> cargowaySkuByDeviceId = cargowaySkuFacade.getCargowaySkuByDeviceId(skuCodes, deviceId);
        skuCodes= cargowaySkuByDeviceId.stream().map(CargowaySkuDO::getSkuCode).distinct().collect(Collectors.toList());
        List<CargowaySkuDO> cargowaySkuList = cargowaySkuByDeviceId.stream().filter(cargowaySkuDO -> cargowaySkuDO.getInventory() > 0).collect(Collectors.toList());

        //按照sku分组，有库存的展示累加库存和 显示列表
        Map<String, Integer> skuCodeInventoryMap = cargowaySkuList.stream().collect(Collectors.groupingBy(CargowaySkuDO::getSkuCode, Collectors.summingInt(CargowaySkuDO::getInventory)));


        //查询sku信息
        Map<String, SkuDTO> skuMap = skuFacade.getSkuMap(skuCodes);
        Map<String, WorkOrderDetailDO> workOrderDetailDOMap = workOrderDetails.stream().collect(Collectors.toMap(WorkOrderDetailDO::getSkuCode, Function.identity()));


        List<UserRoleSkuDTO> userRoleSkuList = skuCodes.stream().map(skuCode -> {
            WorkOrderDetailDO workOrderDetailDO = workOrderDetailDOMap.get(skuCode);

            UserRoleSkuDTO skuQtyDTO1 = new UserRoleSkuDTO();
            SkuDTO skuDTO = skuMap.get(skuCode);
            skuQtyDTO1.setSkuCode(skuDTO.getSkuCode());
            skuQtyDTO1.setSkuImg(skuDTO.getSkuImg());
            skuQtyDTO1.setProductName(skuDTO.getSkuName());
            skuQtyDTO1.setPickStatus(PickStatusEnum.PICKUP_SUCCESS.getCode());
            int inventory = skuCodeInventoryMap.get(skuCode)==null?0:skuCodeInventoryMap.get(skuCode);
            skuQtyDTO1.setPickStatus(inventory>0?PickStatusEnum.PICKUP_SUCCESS.getCode():PickStatusEnum.NO_STOCK.getCode());

            //已领用数量
            int pickUpNum = workOrderDetailDO.getActQty()==null?0:workOrderDetailDO.getActQty();
            //可领用数量
            int  pickUpLimit= workOrderDetailDO.getPlanQty() - workOrderDetailDO.getActQty();
            skuQtyDTO1.setPickUpNum(pickUpNum);
            skuQtyDTO1.setPlanQty(workOrderDetailDO.getPlanQty());
            skuQtyDTO1.setPickUpLimit(pickUpLimit);
            skuQtyDTO1.setInventory(inventory);
            //综合本台柜子最大可领用数量,如果可领用数量大于库存，取库存为最大可领用，反之则取可领用数量
            skuQtyDTO1.setPickUpByInventory(Math.min(inventory, pickUpLimit));

            //可领为0
            if (skuQtyDTO1.getPickUpLimit() <= 0 && inventory> 0) {
                skuQtyDTO1.setPickStatus(PickStatusEnum.OVER_PICKUP.getCode());
            }
            return skuQtyDTO1;
        }).collect(toList());
        //set 库存列表
        cargowaySkuFacade.getSkuInventory(cargowaySkuList, userRoleSkuList, deviceId);
        return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), workOrderDetails.size(), userRoleSkuList);
    }
}

